# coding = gbk
# -*- coding:utf-8 -*-
import copy
import os
import json
import re


# 获取md文件路径
def getMdFile(path):
    '''
    :param path:md文件所在路径
    :return: md文件路径列表
    '''
    mdFiles = []
    with open(path, 'r', encoding='utf-8', errors='ignore') as mdfile:
        mdfileList = mdfile.readlines()
        for file in mdfileList:
            file = file.strip('\n').replace('\\', '/')
            mdFiles.append(file)
    return mdFiles


# 获取kit Subsystem，owner中的全量数据
def getOwners(path):
    excel_path = r"/docs/zh-cn/contribute/docs-owners.md"
    result = {"Kit": set(), "Subsystem": set(), "gitcode_id": set()}
    # kit 列表
    kit_set = set()
    # subsystem
    subsystem_set = set()
    # 运行提交pr人员清单
    gitcode_id_set = set()
    # 当前需要写入的表格
    current_set = set()
    # 标准化路径
    normalized_path = os.path.normpath(path).replace('\\', '/')
    # 分割路径为各个部分
    parts = normalized_path.split(os.sep)
    # 查找并截取到'docs'部分
    if '/docs/' in normalized_path:
        parts = normalized_path.split('/docs/')
        # 重新组合路径c
        new_part = parts[0] + excel_path
        # # 白名单标准化路径
        new_path = os.path.normpath(new_part)
        if os.path.exists(new_path):
            with open(new_path, 'r', encoding='utf-8', errors='ignore') as mdfile:
                lines = mdfile.readlines()
                # 去除所有空行
                lines = [line for line in lines if line.strip()]
                for line in lines:
                    if re.search('^## +Kit *\n', line):
                        current_set = kit_set
                    elif re.search('^## +Subsystem *\n', line):
                        current_set = subsystem_set
                    elif re.match('^# .*?\n', line):
                        continue
                    else:
                        item = line.replace('<br>', '').lstrip().rstrip()
                        current_set.add(item)
        else:
            # 功能上线时的默认值，后续没有的需要自己添加
            kit_set = {'Ability Kit', 'Performance Analysis Kit', 'ArkGraphics 3D', 'ArkTS', 'AVCodec Kit',
                       'AVSession Kit', 'Calendar Kit', 'IDL', 'Camera Kit', 'Test Kit', 'Background Tasks Kit',
                       'User Authentication Kit', 'Input Kit', 'Asset Store Kit', 'Audio Kit', 'Core File Kit',
                       'Drm Kit', 'Sensor Service Kit', 'Connectivity Kit', 'Contacts Kit', 'Distributed Service Kit',
                       'Device Certificate Kit', 'Driver Development Kit', 'Form Kit', 'ArkGraphics 2D', 'Location Kit',
                       'Common', 'Common Basic Capability', 'ArkUI', 'NDK Development', 'NDK',
                       'Function Flow Runtime Kit', 'Localization Kit', 'MDM Kit', 'MindSpore Lite Kit', 'Mechanic Kit',
                       'Media Kit', 'Basic Services Kit', 'ArkWeb', 'Ads Kit', 'Network Kit', 'Notification Kit',
                       'Telephony Kit', 'IPC Kit', 'Security Guard Kit', 'Media Library Kit', 'Universal Keystore Kit',
                       'Data Protection Kit', 'Multimodal Awareness Kit', 'ArkData', 'Crypto Architecture Kit',
                       'Image Kit', 'Accessibility Kit', 'IME Kit'}

            # 功能上线时的默认值，后续没有的需要自己添加
            subsystem_set = {'Location', 'MultimodalInput', 'Demo&Sample', 'Account', 'BarrierFree',
                             'MultimodalAwareness', 'ArkCompiler', 'Base', 'Applications', 'Msdp', 'XTS',
                             'DistributedHardware', 'Security', 'Graphic', 'Advertising', 'WindowManager',
                             'ResourceSchedule', 'USB', 'DistributedDataManager', 'Common', 'Window', 'ArkUI', 'Global',
                             'Multimedia', 'Ability', 'Request', 'Customization', 'Test', 'SelectionInput', 'UserIAM',
                             'AI', 'Utils', 'Update', 'Web', 'Driver', 'Telephony', 'SystemManagementServices',
                             'Startup', 'Sensors', 'Developtools', 'MiscServices', 'PowerManager', 'Communication',
                             'Mechanic', 'HiviewDFX', 'CommonLibrary', 'BundleManager', 'DistributedSched', 'Time',
                             'FileManagement', 'arkcompiler', 'Graphics', 'Resourceschedule', 'Print', 'Notification'}

            gitcode_id_set = set()

    result["Kit"] = kit_set
    result["Subsystem"] = subsystem_set
    result["gitcode_id"] = gitcode_id_set
    return result


# 检查kit或subsystem是否在表格中,0无异常，1:格式错误，2：为空，3：设置数量超过三个人
def check_gitcode_id(result):
    if ';' in result:
        result_list = result.split(';')
        if len(result_list) > 3:
            return 3
        for s in result_list:
            if s == '' or str.isspace(s):
                return 2
            elif not validate_string(s):
                return 1
    else:
        if not validate_string(result):
            return 1
    return 0


# 检查'Owner', 'SE', 'TSE' 填写账号需要满足1、以@开头，2、是否符合gitCode的要求:只允许字母、数字或者下划线（_）、中划线（-），3到50个字符，必须以字母开头。
def validate_string(gitcode_id):
    gitcode_id = gitcode_id.lstrip()

    if not gitcode_id.startswith("@"):
        return False
    gitcode_id = gitcode_id.replace("@", '')
    # 检查长度
    if len(gitcode_id) < 3 or len(gitcode_id) > 50:
        return False
    # 检查是否以字母开头
    if not gitcode_id[0].isalpha():
        return False
    # 检查每个字符是否符合要求
    for char in gitcode_id:
        if not (char.isalnum() or char == '_' or char == '-'):
            return False
    return True


# CI扫描时获取md文件路径
def getMdFileforCI(top):
    '''
    :param top:md文件所在路径
    :return: md文件路径列表
    '''
    mdFiles = []
    for root, dirs, files in os.walk(top, topdown=False):
        root = root.replace('\\', '/')
        for fileName in files:
            fileNameList = fileName.split('.')
            if fileNameList[-1] == 'md':
                mdPath = os.path.join(root, '.'.join(fileNameList))
                mdPath = mdPath.replace('\\', '/')
                mdFiles.append(mdPath)
    return mdFiles


# 保存扫描结果到本目录
def saveResult(resultDic):
    '''
    :param resultDic: 扫描结果保存字典
    '''
    # 保存到当前路径，获取后需要删除
    if os.path.exists(os.path.join(os.path.realpath(os.path.dirname(__file__)), "result.txt")):
        os.remove(os.path.join(os.path.realpath(os.path.dirname(__file__)), "result.txt"))
    savePath = os.path.join(os.path.realpath(os.path.dirname(__file__)), "result.txt")
    try:
        with open(savePath, 'w', encoding="utf-8") as f:
            f.write(json.dumps(resultDic, ensure_ascii=False, indent=4))
    except FileNotFoundError as e:
        print(e)


# 检查文件是否有忽略检查注释
def if_no_check(path):
    '''
    :param path: 文件路径
    :return: 存在<!--no_check-->标签返回True，不存在返回False
    '''
    try:
        with open(path, 'r', encoding='utf-8', errors='ignore') as f:
            lines = f.readlines()
            last_valid_line_num = len(lines) - 1
            last_line = None
            while last_valid_line_num >= 0:
                last_line = lines[last_valid_line_num]
                # 兼容末尾空行和空格写法
                last_line = last_line.replace(" ", "").replace("\n", "")
                if not last_line:
                    last_valid_line_num -= 1
                else:
                    break
            if last_line == "<!--no_check-->":
                return True
            else:
                return False
    except FileNotFoundError as e:
        print(e)


# 获取文件内容，返回内容字符串
def get_file_data(path):
    '''
    :param path: 文件路径
    :return: 文件内容
    '''
    data = ''
    try:
        with open(path, 'r', encoding='utf-8', errors='ignore') as f:
            data = f.read()
    except FileNotFoundError as e:
        print(e)
    return data


# 获取去除代码示例后的文档内容
def get_data_without_code(content):
    '''
    :param content:文档内容
    :return:去掉代码后的文档内容
    '''
    code_data_list = get_code_data(content)
    if code_data_list:
        for code_block in code_data_list:
            content = content.replace(code_block, '')
    return content


# 获取文件中的代码块
def get_code_data(content):
    '''
    :param content: 文档内容
    :return: 文档中的代码块
    '''
    pattern = re.compile(r'```[\s\S]+?```')
    code_data = re.findall(pattern, content)
    return code_data


# 获取readme内容
# path:readme路径，root_path：readme所在文件夹路径，spacenum：每一行需要添加的缩进
def get_readme_content(path, root_path, website: list, spacenum):
    '''
    :param path: readme路径
    :param root_path: readme所在文件夹路径
    :param website: website列表
    :param spacenum: 每一行需要添加的缩进
    :return: 生成的website
    '''
    root_path = root_path.replace('\\', '/')
    try:
        with open(path, 'r', encoding='utf-8', errors='ignore') as f:
            data = f.readlines()
            data_copy = copy.deepcopy(data)
            for line in data_copy:
                if '#' in line:
                    data.remove(line)
            # 将不包含嵌套的行直接取出放入列表，嵌套的内容获取到readme路径，然后采用递归调用当前方法，最终返回结果列表
            for line in data:
                if '](' in line and 'Readme' not in line:
                    # 拼接website内容路径
                    line = line.split('](')
                    # 文件夹+文件名
                    line[1] = path.split('/application-dev/')[-1].replace('/Readme-CN.md', '') + '/' + line[1]
                    line = ']('.join(line)
                    website.append(' ' * spacenum + line)
                elif '](' in line and 'Readme' in line:
                    website.append(' ' * spacenum + line.split('](')[0].replace('[', ''))
                    # 拼接Readme路径
                    readme_path = line.split('](')[-1].rstrip('\n').rstrip(' ').rstrip(')')
                    readme_path_list = readme_path.split('/')
                    count = readme_path_list.count('..')
                    if isinstance(root_path, list):
                        root_path = '/'.join(root_path)
                    root_path = root_path.split('/')
                    if count == 1:
                        readme_path_list.pop(0)
                        readme_path = root_path[:-1] + readme_path_list
                    elif count == 2:
                        del readme_path_list[0:2]
                        readme_path = root_path[:-2] + readme_path_list
                    else:
                        readme_path = root_path + readme_path_list
                    readme_path = '/'.join(readme_path)
                    # 嵌套内容的缩进
                    embeded_space_str = re.findall('[ ]+(?=- )', website[-1])
                    if embeded_space_str:
                        embeded_spacenum = embeded_space_str[0].count(' ') + 2
                    else:
                        embeded_spacenum = 2
                    # 嵌套递归处理
                    embeded_root_path = '/'.join(readme_path.split('/')[:-1])
                    get_readme_content(readme_path, embeded_root_path, website, embeded_spacenum)
                else:
                    website.append(' ' * spacenum + line)
    except FileNotFoundError as e:
        raise e
    return website


# 查找docs发布包中重复的docCode
def find_same_doccode(path):
    '''
    :param path: docs发布包路径
    :return: 重复的doccode
    '''
    try:
        with open(path, 'r', encoding='utf-8',errors='ignore') as f:
            result = []
            doccodes = []
            data = f.read()
            data = json.loads(data)
            for item in data:
                if item['docCode'] in doccodes:
                    result.append(item['docCode'])
                else:
                    doccodes.append(item['docCode'])
    except FileNotFoundError as e:
        print(e)
    return result
